<!-- 
名称：题目列表
时间：2025-04-07 18:28:38 
-->
<template>
	<div class="question-container" :key="quesItem.questionId">
		<div class="question-list">
			<div class="question-item">
				<!-- 标头 -->
				<div class="question-header" v-if="showTaskHeader">
					<div class="question-left">
						<!-- 题型 -->
						<div class="question-type">
							{{ quesItem.quesType?.name }}
						</div>
						<!-- 共用选项题分数 -->
						<div v-if="QUES_TYPE_CHAR[quesItem.quesStruct] == '共用选项题'">
							共{{
								(quesItem?.answer?.length || quesItem?.children?.length) *
									quesItem.score || 0
							}}分
						</div>
						<!-- 分数 -->
						<div class="question-score">
							<template v-if="QUES_TYPE_CHAR[quesItem.quesStruct] == '多选题'">
								{{
									`全对${quesItem.score || 0}分 漏选${quesItem.scoreWhenMissingOptions || 0}分 错选${quesItem.scoreWhenSelectingWrongOptions || 0}分`
								}}
							</template>
							<template v-else>
								<!-- 共用选项题 -->
								<span
									v-if="QUES_TYPE_CHAR[quesItem.quesStruct] == '共用选项题'"
									class="share-option-score"
								>
									<span
										>{{
											quesItem?.answer?.length || quesItem?.children?.length
										}}小题</span
									>
									<span>每小题</span>
								</span>
								<!-- 多小题 -->
								<span v-if="QUES_TYPE_CHAR[quesItem.quesStruct] == '多小题'"
									>共</span
								>
								{{ quesItem.score || 0 }} 分
							</template>
						</div>
						<!-- 难度 -->
						<div class="question-difficulty" v-if="quesItem.difficulty?.name">
							{{ quesItem.difficulty?.name }}
						</div>
						<!-- 批阅类型 -->
						<div>{{ quesItem.gradingType }}</div>
						<!-- 共享范围 -->
						<div v-if="quesItem.useRangeType != 0">
							{{ showUserRange(quesItem.useRangeType) }}
						</div>
						<!-- 使用次数 -->
						<div class="question-used">
							使用 {{ quesItem.useCount || 0 }} 次
						</div>
					</div>
					<div class="question-source text-ellipsis">
						{{ quesItem.questionSource }}
					</div>
				</div>
				<div class="question-center">
					<!-- 题目及解析 -->
					<cx-collapse v-model="computedExpand">
						<!-- 题目 -->
						<custom-div
							v-if="quesItem.context?.stem"
							class="question-content"
							:defaultString="`<div>${quesItem.context?.stem}</div>`"
						></custom-div>
						<!-- 选项 -->
						<div
							class="ques-options"
							:ref="(ref: any) => optionStyle(ref)"
							v-if="quesItem.context?.options?.length && reFresh"
						>
							<div
								class="ques-option"
								v-for="(option, subIndex) in quesItem.context?.options"
								:key="subIndex"
							>
								<div class="option-index">
									{{ String.fromCharCode(65 + subIndex) }}.
								</div>
								<custom-div
									class="option-content"
									:defaultString="option"
								></custom-div>
							</div>
						</div>
						<!-- 多小题情况 -->
						<div
							class="ques-child-item"
							v-for="(child, childIndex) in quesItem.children"
							:key="child.questionId"
						>
							<div class="child-header">
								<div class="question-score">
									<template v-if="child.quesType.name == '多选题'">
										{{
											`全对${child.score || 0}分 漏选${child.scoreWhenMissingOptions || 0}分 错选${child.scoreWhenSelectingWrongOptions || 0}分`
										}}
									</template>
									<template v-else> {{ child.score || 0 }} 分 </template>
								</div>
								<div class="child-type">{{ child.quesType.name }}</div>
								<div class="review-type">
									{{
										['14', '15'].includes(child.quesStruct)
											? '人工批阅'
											: '自动批阅'
									}}
								</div>
							</div>
							<div class="child-title">
								<div class="child-index">
									{{ `(${(child?.index ?? childIndex) + 1})` }}
								</div>
								<custom-div :defaultString="child.context.stem"> </custom-div>
							</div>
							<div
								class="ques-options"
								v-if="child.context?.options?.length && reFresh"
								:ref="(ref: any) => optionStyle(ref)"
							>
								<div
									class="ques-option"
									v-for="(option, subIndex) in child.context?.options"
									:key="subIndex"
								>
									<div class="option-index">
										{{ String.fromCharCode(65 + subIndex) }}.
									</div>
									<custom-div
										class="option-content"
										:defaultString="option"
									></custom-div>
								</div>
							</div>
							<!-- 学生作答详情 -->
							<slot
								name="answer-detail"
								:id="child.questionId"
								:cIndex="child?.index ?? childIndex"
							/>
						</div>
						<template #collapse-content>
							<div class="question-parse">
								<div class="answer-content">
									<div class="answer-title">答案</div>
									<custom-div
										class="answer-text"
										:defaultString="getAnswerString(quesItem)"
									></custom-div>
								</div>
								<div class="parse-content">
									<div class="parse-title">解析</div>
									<custom-div
										class="parse-text"
										:defaultString="getAnalysisString(quesItem)"
									></custom-div>
								</div>
							</div>
						</template>
					</cx-collapse>
					<!-- 题目知识点 -->
					<div class="question-tags">
						<div
							class="tag"
							v-for="(tag, index) in quesItem?.knowledge"
							:key="tag.code"
						>
							{{ tag.name }}
						</div>
					</div>
					<!-- 学生作答详情 -->
					<div style="margin-top: 12px">
						<slot
							name="answer-detail"
							:id="id"
							v-if="!quesItem.children?.length"
						/>
					</div>
				</div>
				<!-- 底部 -->
				<div class="question-footer" v-if="showExpand">
					<div class="open-parse" @click="expand = !expand">
						{{ expand ? '收起解析' : '展开解析' }}
						<svg-icon
							size="12px"
							name="allowBottom"
							class="arrow-down"
							:class="{ 'rotate-reverse': expand }"
						></svg-icon>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts">
import { debounce } from 'lodash-es'
import CxCollapse from '@/components/collapse/index.vue'
import useQuestionList from '@/hooks/useQuestionList'
import { QUES_TYPE_CHAR } from '@/assets/common/form'

const props = withDefaults(
	defineProps<{
		quesItem: Record<string, any>
		id: string
		parentId: string | null
		showExpand?: boolean
		showTaskHeader?: boolean
	}>(),
	{
		showExpand: true,
		showTaskHeader: false
	}
)
const expand = ref(false)
const { getAnswerString, getAnalysisString } = useQuestionList()
const reFresh = ref(true)
const handleResize = debounce(async () => {
	reFresh.value = false
	await nextTick()
	reFresh.value = true
}, 200)
window.addEventListener('resize', handleResize)

const optionStyle = async (dom: HTMLElement) => {
	await nextTick()
	if (!dom) return
	const optionDoms = Array.from(dom.querySelectorAll('.ques-option'))
	const boxWidth = dom.getBoundingClientRect().width
	const maxWidth = Math.max(
		...optionDoms.map((item) => item.getBoundingClientRect().width)
	)
	const totalWidth = optionDoms.reduce(
		(pre, cur) => pre + cur.getBoundingClientRect().width,
		0
	)
	// 一行排列
	if (totalWidth < boxWidth) {
		dom.style.flexDirection = 'row'
		dom.style.justifyContent = 'space-between'
		optionDoms.forEach((item) => {
			item.style.alignItems = 'center'
		})
		return
	}
	// 一行两列
	if (maxWidth <= boxWidth / 2) {
		dom.style.display = 'grid'
		dom.style.gridTemplateColumns = 'repeat(2, 1fr)'
		optionDoms.forEach((item) => {
			item.style.alignItems = 'center'
		})
		return
	}
}
const showUserRange = (item: number) => {
	if (item == 1) return '本单位共享'
	return '仅个人使用'
}
watch([() => props.id], () => {
	expand.value = false
})
const computedExpand = computed(() => {
	if (!props.showExpand) return true
	return expand.value
})
onBeforeUnmount(() => {
	window.removeEventListener('resize', handleResize)
})
</script>

<style lang="less" scoped>
.question-container {
	height: 100%;
	.question-list {
		.question-score {
			.multi-score {
				display: flex;
				align-items: center;
				gap: 8px;
				> div {
					display: flex;
					align-items: center;
					gap: 4px;
				}
			}
			:deep(.arco-input-wrapper) {
				width: 69px;
			}
		}
		.question-item {
			background-color: #fff;
			border-radius: 16px;
			&:not(:first-child) {
				margin-top: 8px;
			}
			.question-header {
				height: 44px;
				padding: 12px 16px;
				width: 100%;
				display: flex;
				align-items: center;
				justify-content: space-between;
				border-bottom: 1px solid #f2f5fa;
				color: #474f59;
				.question-left {
					display: flex;
					align-items: center;
					div:first-child {
						padding-left: 0px;
					}
					.question-score,
					.question-index {
						padding-right: 8px;
					}
					> div {
						padding: 0 8px;
					}
					> div:not(:first-child) {
						position: relative;
						&::before {
							position: absolute;
							content: '';
							width: 1px;
							height: 8px;
							background-color: #e1e5eb;
							left: 0;
							top: 50%;
							transform: translateY(-50%);
						}
					}
				}
				.question-source {
					max-width: 40%;
					color: #99a1ad;
				}
			}
			.question-center {
				padding: 12px 16px;
				.question-content {
					display: flex;
					flex-direction: column;
					gap: 8px;
					line-height: 22px;
				}
				.ques-options {
					margin-top: 8px;
					display: flex;
					flex-direction: column;
					gap: 8px;
					.ques-option {
						display: flex;
						align-items: baseline;
						line-height: 24px;
						width: fit-content;
						.option-index {
							margin-right: 4px;
							font-weight: 600;
							color: #333;
						}
					}
				}
				.ques-child-item {
					margin-top: 8px;
					align-items: baseline;
					.child-header {
						display: flex;
						align-items: center;
						margin-bottom: 8px;
						> div {
							color: #99a1ad;
							padding: 0 7px;
							position: relative;
							&::before {
								position: absolute;
								content: '';
								width: 1px;
								height: 8px;
								background-color: #e1e5eb;
								left: 0;
								top: 50%;
								transform: translateY(-50%);
							}
						}
						> div:first-child {
							padding-left: 0;
							&::before {
								content: unset;
							}
						}
					}
					.child-title {
						display: flex;
						line-height: 24px;
						.child-index {
							color: #0d1014;
							margin-right: 4px;
							flex-shrink: 0;
						}
					}
				}
				.cart-child-item {
					background-color: #fafbfc;
					padding: 12px;
					border-radius: 8px;
				}
				.question-parse {
					margin-top: 8px;
					padding: 12px;
					display: flex;
					flex-direction: column;
					gap: 12px;
					background-color: #fafbfc;
					border: 1px solid #f2f5fa;
					border-radius: 8px;
					.answer-content,
					.parse-content {
						display: flex;
						align-items: baseline;
						line-height: 24px;
						gap: 8px;
					}
					.answer-title {
						color: #26a555;
						flex-shrink: 0;
					}
					.parse-title {
						color: #ffa126;
						flex-shrink: 0;
					}
				}
				.question-tags {
					margin-top: 10px;
					display: flex;
					margin-left: -4px;
					flex-wrap: wrap;
					.tag {
						max-width: 300px;
						white-space: nowrap;
						overflow: hidden;
						text-overflow: ellipsis;
						margin-top: 6px;
						margin-left: 4px;
						height: 24px;
						line-height: 24px;
						text-align: center;
						padding: 0 8px;
						background-color: #f5f7fa;
						color: #557ca7;
						border-radius: 4px;
					}
					.edit-knowledge {
						cursor: pointer;
					}
				}
			}
			.question-footer {
				padding: 0px 16px;
				display: flex;
				justify-content: space-between;
				align-items: center;

				.open-parse {
					color: #557ca7;
					cursor: pointer;
					user-select: none;
					.arrow-down {
						margin-left: 4px;
						transition: all 0.3s;
					}
					.rotate-reverse {
						transform: rotate(180deg);
					}
				}
			}
		}
	}
}
</style>
